package sfeir.gwt.ergosoom.server.util;

import sfeir.gwt.ergosoom.client.model.Address;
import sfeir.gwt.ergosoom.client.model.Email;
import sfeir.gwt.ergosoom.client.model.GeoLocalisation;
import sfeir.gwt.ergosoom.client.model.NetworkItem;
import sfeir.gwt.ergosoom.client.model.Person;
import sfeir.gwt.ergosoom.client.model.Tel;

public class VCardParser extends VCardResultParser {

    public static Person parse(String rawText) {

        if (rawText == null || !rawText.startsWith("BEGIN:VCARD"))
            return null;
        // || !rawText.endsWith("END:VCARD")) {
        // }

        Pair<String, String>[] names = matchVCardPrefixedField("N", rawText, true);
        if (names == null) {
            // If no display names found, look for regular name fields and
            // format them
            names = matchVCardPrefixedField("FN", rawText, true);
            formatNames(names);
        }
        Pair<String, String>[] phoneNumbers = matchVCardPrefixedField("TEL", rawText, true);
        Pair<String, String>[] emails = matchVCardPrefixedField("EMAIL", rawText, true);
        Pair<String, String> note = matchSingleVCardPrefixedField("NOTE", rawText, false);
        Pair<String, String>[] addresses = matchVCardPrefixedField("ADR", rawText, true);
        Pair<String, String> org = matchSingleVCardPrefixedField("ORG", rawText, true);
        if (org != null)
            org.setSecond(org.getSecond().replaceAll(";", " - "));
        Pair<String, String> birthday = matchSingleVCardPrefixedField("BDAY", rawText, true);
        // if (birthday != null && !isStringOfDigits(birthday, 8)) {
        // return null;
        // }
        Pair<String, String> title = matchSingleVCardPrefixedField("TITLE", rawText, true);
        Pair<String, String> geo = matchSingleVCardPrefixedField("GEO", rawText, true);
        Pair<String, String>[] networks = matchVCardPrefixedField("URL", rawText, true);
        Pair<String, String> nickname = matchSingleVCardPrefixedField("NICKNAME", rawText, true);

        Person p = new Person();
        if (null != names) {
            String[] n = formatNames(names);
            p.setName(n[0]);
            p.setFirstname((n.length > 1) ? n[1] : "");
        }
        if (null != org)
            p.setCompany(org.getSecond());
        if (null != note)
            p.setAboutMe(note.getSecond());
        if (null != title)
            p.setTitle(title.getSecond());
        if (null != birthday)
            p.setBirthDay(birthday.getSecond());
        if (null != nickname)
            p.setNickname(nickname.getSecond());
        if (null != geo) {
            String[] coords = geo.getSecond().split(";");
            if (null != coords && 1 < coords.length)
                p.setGeo(new GeoLocalisation(Double.parseDouble(coords[0]), Double.parseDouble(coords[1])));
        }

        if (networks != null) {
            for (Pair<String, String> pair : networks) {
                String s = pair.getSecond();
                if (s.endsWith(".jpg") || s.endsWith(".jpeg") || s.endsWith(".png") || s.endsWith(".gif")
                        || s.endsWith(".bmp"))
                    p.setPhoto(s);
                else {
                    String[] types = { "facebook", "twitter", "linkedin", "dopplr", "vimeo", "viadeo", "friendfeed" };
                    for (String st : types)
                        if (s.contains(st))
                            p.getNetworkItems().add(new NetworkItem(st, s));
                }
            }
        }

        if (null != phoneNumbers) {
            for (Pair<String, String> phone : phoneNumbers) {
                String type = phone.getFirst();
                if (null != type) {
                    if ("CELL".equals(type))
                        p.getTels().add(new Tel(phone.getSecond(), Tel.MOBILE_LINE));
                    else if ("WORK".equals(type))
                        p.getTels().add(new Tel(phone.getSecond(), Tel.PROFESSIONNAL_LINE));
                    else
                        p.getTels().add(new Tel(phone.getSecond(), Tel.HOME_LANDLINE));
                } else
                    p.getTels().add(new Tel(phone.getSecond(), Tel.HOME_LANDLINE));
            }
        }
        if (null != emails) {
            for (Pair<String, String> email : emails) {
                String type = email.getFirst();
                if (null != type) {
                    if ("WORK".equals(type))
                        p.getEmails().add(new Email(email.getSecond(), Email.PROFESSIONNAL_EMAIL));
                    else
                        p.getEmails().add(new Email(email.getSecond(), Email.PERSONAL_EMAIL));
                } else
                    p.getEmails().add(new Email(email.getSecond(), Email.UNKNOWN));
            }
        }
        if (null != addresses) {
            for (Pair<String, String> addr : addresses) {
                addr = formatAddress(addr);
                String type = addr.getFirst();
                if (null != type) {
                    if ("WORK".equals(type))
                        p.getAddresses().add(new Address(addr.getSecond(), Address.PROFESSIONNAL_ADDRESS));
                    else
                        p.getAddresses().add(new Address(addr.getSecond(), Address.PERSONAL_ADDRESS));
                } else
                    p.getAddresses().add(new Address(addr.getSecond(), Address.DEFAULT_ADDRESS));
            }
        }
        return p;
    }
}
